package routes

import (
	"baseService/internal/interfaces/http/handlers"
	"net/http"
	"time"

	"baseService/internal/application"
	"baseService/internal/interfaces/http/middleware/accesslog"
	"baseService/internal/interfaces/http/middleware/cors"
	"baseService/internal/interfaces/http/middleware/ratelimit"
	"baseService/internal/interfaces/http/middleware/tracing"
	"baseService/internal/pkg/response"
	"baseService/internal/pkg/websocket"

	"github.com/gin-gonic/gin"
)

// Router 路由管理器 - 持有应用上下文
type Router struct {
	ctx *application.AppContext
}

// NewRouter 创建路由管理器
func NewRouter(ctx *application.AppContext) *Router {
	return &Router{ctx: ctx}
}

// Setup 设置所有路由
func (r *Router) Setup(engine *gin.Engine) error {
	// 添加全局中间件
	r.setupGlobalMiddleware(engine)

	// 健康检查路由
	r.setupHealthRoutes(engine)

	// API路由组
	r.setupAPIRoutes(engine)

	// 静态文件服务
	r.setupStaticFiles(engine)

	// WebSocket路由
	r.setupWebSocketRoutes(engine)

	// 404处理
	engine.NoRoute(func(c *gin.Context) {
		response.NotFound(c, "路由不存在")
	})

	r.ctx.Logger.Info("路由设置完成")
	return nil
}

// setupGlobalMiddleware 设置全局中间件
func (r *Router) setupGlobalMiddleware(engine *gin.Engine) {
	// 错误恢复中间件
	engine.Use(gin.CustomRecovery(func(c *gin.Context, recovered interface{}) {
		r.ctx.Logger.Errorf("panic recovered: %v", recovered)
		response.InternalError(c, "服务器内部错误")
		c.Abort()
	}))

	// CORS中间件
	corsConfig := &r.ctx.Config.Middleware.CORS
	if corsConfig.Enable {
		corsMiddleware := cors.NewCORSMiddleware(corsConfig, r.ctx.Logger)
		engine.Use(corsMiddleware.Handler())
	}

	// 链路追踪中间件 - 使用配置文件
	tracingConfig := &r.ctx.Config.Middleware.Tracing
	if tracingConfig.Enable {
		tracingMiddleware := tracing.NewMiddleware(tracingConfig, r.ctx.Logger)
		engine.Use(tracingMiddleware.Handler())
	}

	// 响应器中间件 - 统一请求级响应与元数据
	engine.Use(response.ResponderMiddleware())

	// 限流中间件
	rateLimitConfig := &r.ctx.Config.Middleware.RateLimit
	if rateLimitConfig.Enable {
		rateLimitMiddleware := ratelimit.NewMiddleware(rateLimitConfig, r.ctx.Logger)
		engine.Use(rateLimitMiddleware.Handler())
	}

	// 访问日志中间件 - 根据环境自动配置
	accessLogMiddleware, err := accesslog.NewEnvironmentMiddleware(
		r.ctx.Config.App.Environment,
		r.ctx.Config.Log,
		r.ctx.Logger,
	)
	if err != nil {
		r.ctx.Logger.Warnf("访问日志中间件初始化失败: %v", err)
	} else {
		engine.Use(accessLogMiddleware.Handler())
		r.ctx.Logger.Info("访问日志中间件已启用")
	}

	// 开发环境额外启用Gin的Logger（彩色输出）
	if r.ctx.IsDevelopment() {
		engine.Use(gin.Logger())
	}
}

// setupHealthRoutes 设置健康检查路由
func (r *Router) setupHealthRoutes(engine *gin.Engine) {
	// 基础健康检查
	engine.GET("/health", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"status":      "healthy",
			"timestamp":   time.Now().Unix(),
			"environment": r.ctx.Config.App.Environment,
			"version":     r.ctx.Config.App.Version,
		})
	})

	// 详细健康检查
	engine.GET("/health/detail", func(c *gin.Context) {
		health := r.checkHealth()
		status := http.StatusOK
		if !health["healthy"].(bool) {
			status = http.StatusServiceUnavailable
		}
		c.JSON(status, health)
	})

	// 数据库连接池状态
	engine.GET("/health/db", func(c *gin.Context) {
		stats, err := r.ctx.GetConnectionStats()
		if err != nil {
			response.InternalError(c, "获取数据库状态失败")
			return
		}
		response.Success(c, stats)
	})
}

// setupAPIRoutes 设置API路由
func (r *Router) setupAPIRoutes(engine *gin.Engine) {
	v1Group := engine.Group("/api/v1")

	// 用户管理路由
	userHandler := handlers.NewUserHandler(r.ctx, r.ctx.UserService())

	userGroup := v1Group.Group("/users")
	{
		userGroup.GET("", userHandler.GetUsers)
		userGroup.GET("/:id", userHandler.GetUser)
		userGroup.POST("", userHandler.CreateUser)
		userGroup.PUT("/:id", userHandler.UpdateUser)
		userGroup.DELETE("/:id", userHandler.DeleteUser)
	}
}

// setupStaticFiles 设置静态文件服务
func (r *Router) setupStaticFiles(engine *gin.Engine) {
	// 静态文件服务
	engine.Static("/public", "./public")
	engine.Static("/storage", "./storage")

	// 模板文件（如果需要）
	engine.LoadHTMLGlob("templates/*")
}

// setupWebSocketRoutes 设置WebSocket路由
func (r *Router) setupWebSocketRoutes(engine *gin.Engine) {
	r.ctx.Logger.Info("设置WebSocket路由")

	// 使用简化的 WebSocket 服务
	engine.GET("/ws", func(c *gin.Context) {
		// 使用 Melody 处理 WebSocket 连接
		websocket.HandleUpgrade(c)
	})

	// WebSocket 状态信息端点（可选）
	engine.GET("/ws/stats", func(c *gin.Context) {
		stats := websocket.GetStats()
		response.Success(c, stats)
	})
}

// checkHealth 检查服务健康状态
func (r *Router) checkHealth() map[string]interface{} {
	healthy := true
	components := make(map[string]interface{})

	// 检查数据库
	if r.ctx.DB != nil {
		sqlDB, err := r.ctx.DB.DB()
		if err != nil {
			healthy = false
			components["database"] = map[string]interface{}{
				"status": "unhealthy",
				"error":  err.Error(),
			}
		} else if err := sqlDB.Ping(); err != nil {
			healthy = false
			components["database"] = map[string]interface{}{
				"status": "unhealthy",
				"error":  err.Error(),
			}
		} else {
			stats := sqlDB.Stats()
			components["database"] = map[string]interface{}{
				"status":           "healthy",
				"open_connections": stats.OpenConnections,
				"in_use":           stats.InUse,
				"idle":             stats.Idle,
			}
		}
	}

	// 检查缓存
	if r.ctx.Cache != nil {
		testKey := "_health_check"
		testValue := time.Now().Unix()

		if err := r.ctx.Cache.Set(testKey, testValue, 1*time.Second); err != nil {
			healthy = false
			components["cache"] = map[string]interface{}{
				"status": "unhealthy",
				"error":  err.Error(),
			}
		} else {
			cachedValue, found := r.ctx.Cache.Get(testKey)
			result, ok := cachedValue.(int64)
			if !found || !ok || result != testValue {
				healthy = false
				components["cache"] = map[string]interface{}{
					"status": "unhealthy",
					"error":  "cannot retrieve test value",
				}
			} else {
				components["cache"] = map[string]interface{}{
					"status": "healthy",
				}
			}
		}
	}

	// 检查事件总线
	if r.ctx.EventBus != nil {
		components["eventbus"] = map[string]interface{}{
			"status": "healthy",
			"type":   "simple", // 简化版事件总线
		}
	}

	return map[string]interface{}{
		"healthy":     healthy,
		"timestamp":   time.Now().Unix(),
		"environment": r.ctx.Config.App.Environment,
		"version":     r.ctx.Config.App.Version,
		"components":  components,
	}
}
